/*****************************************************************************
 *                                                                           *
 *   Copyright (C) 2010 by Luca Cireddu                                      *
 *                         luca@lucacireddu.it                               *
 *                         http://www.lucacireddu.it                         *
 *                                                                           *
 *   This program is free software; you can redistribute it and/or modify    *
 *   it under the terms of the GNU General Public License as published by    *
 *   the Free Software Foundation; either version 2 of the License.          *
 *                                                                           *
 *   This program is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *   GNU General Public License for more details.                            *
 *                                                                           *
 *   You should have received a copy of the GNU General Public License       *
 *   along with this program; if not, write to the                           *
 *   Free Software Foundation, Inc.                                          *
 *   51 Franklin Street, Fifth Floor                                         *
 *   Boston, MA  02110-1301, USA.                                            *
 *                                                                           *
 *****************************************************************************/

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gd.h>

#include "common.h"
#include "grphimages.h"
#include "defines.h"
#include "ngexit.h"
#include "parseargs.h"
#include "datacollect.h"

extern graph_param params;
extern int grph_x;
extern int grph_y;

void createGraph(data_collect *data)
{
    gdImagePtr img;
    int i;
    int shift_r, shift_g, shift_b;
    int color_trans, color_black, color_rx, color_tx;
    int val_rx, val_tx;
    int grph_gradient[params.outy - (BORDER_TOP + BORDER_BOTTOM + 2)];
    FILE *write;
    pntdata *grph_points;

    img = gdImageCreate(params.outx, params.outy);

    color_trans = gdImageColorAllocateAlpha(img, 255, 255, 255, 127);
    color_black = gdImageColorAllocateAlpha(img, 0, 0, 0, 0);
    color_rx = gdImageColorAllocateAlpha(img, 255, 255, 0, 0);
    color_tx = gdImageColorAllocateAlpha(img, 255, 0, 0, 0);

    for(i = 0; i < grph_y; i++) {
        shift_r = (int) ((float) i / (grph_y - 1) * (GRAPH_BG_BOTTOM_R - GRAPH_BG_TOP_R));
        shift_g = (int) ((float) i / (grph_y - 1) * (GRAPH_BG_BOTTOM_G - GRAPH_BG_TOP_G));
        shift_b = (int) ((float) i / (grph_y - 1) * (GRAPH_BG_BOTTOM_B - GRAPH_BG_TOP_B));
        grph_gradient[i] = gdImageColorAllocateAlpha(img, (GRAPH_BG_TOP_R + shift_r), (GRAPH_BG_TOP_G + shift_g), (GRAPH_BG_TOP_B + shift_b), 0);
        gdImageLine(img, (BORDER_LEFT + 1), (BORDER_TOP + 1) + i, params.outx - (BORDER_RIGHT + 1), (BORDER_TOP + 1) + i, grph_gradient[i]);
    }

    gdImageRectangle(img, BORDER_LEFT, BORDER_TOP, params.outx - (BORDER_RIGHT + 1), params.outy - (BORDER_BOTTOM + 1), color_black);

    grph_points = createPntData(data);

    for(i = 0; i < grph_x; i++) {
        val_rx = (grph_points + i)->value_rx;
        val_tx = (grph_points + i)->value_tx;

        if(val_rx > (grph_y - 1))
            val_rx = grph_y - 1;

        if(val_tx > (grph_y - 1))
            val_tx = grph_y - 1;

        if(val_rx < 0)
            val_rx = 0;

        if(val_tx < 0)
            val_tx = 0;

        /*
        gdImageSetPixel(img, (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2 + val_rx), color_rx);
        gdImageSetPixel(img, (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2 + val_tx), color_tx);
        */

        gdImageLine(img, (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2), (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2 + val_rx), color_rx);
        gdImageLine(img, (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2), (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2 + val_tx), color_tx);

        if(val_tx > val_rx) {
            gdImageSetPixel(img, (BORDER_LEFT + 1) + i, params.outy - (BORDER_BOTTOM + 2 + val_rx), color_rx);
        }

        if(params.verbose == B_TRUE)
            printf("%d %d | ", val_rx, val_tx);
    }

    if(params.verbose == B_TRUE)
        printf("\n\n");

    write = fopen(IMAGE_TMPFILE, "wb");
    gdImagePng(img, write);
    fclose(write);

    gdImageDestroy(img);

    free(grph_points);
}

pntdata *createPntData(data_collect *data)
{
    pntdata *ret;
    int i, num, diff;
    long long unsigned int max_rx, max_tx;

    ret = (pntdata *) malloc(grph_x * sizeof(pntdata));

    do {
        data = data->next;
    } while(data->id != 0);

    num = 0;

    do {
        num++;
        data = data->next;
    } while(data->id != 0);

    diff = 0;

    if(num > grph_x) {
        diff = num - grph_x;
        num = grph_x;
    }

    for(i = 0; i < diff; i++)
        data = data->next;

    max_rx = params.max_rx * 1024 * params.interval;
    max_tx = params.max_tx * 1024 * params.interval;

    for(i = 0; i < diff; i++)
        data = data->next;

    for(i = 0; (i < grph_x) && (i < num); i++) {
        (ret + i)->value_rx = grph_y * ((float) data->byte_rx / (float) max_rx);
        (ret + i)->value_tx = grph_y * ((float) data->byte_tx / (float) max_tx);
        data = data->next;
    }

    for(i = num; i < grph_x; i++) {
        (ret + i)->value_rx = 0;
        (ret + i)->value_tx = 0;
    }

    return ret;
}
